#include "dcaudio.h"

DcAudio::DcAudio()
{
}

DcAudio::~DcAudio()
{
    audio->stop();
    net_thread.quit();
    net_thread.wait();
}

QAudioFormat *DcAudio::setRecord()
{
    format.setSampleRate(16000);
    format.setChannelCount(1);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::SignedInt);

    QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
    if(!info.isFormatSupported(format)){
        qWarning()<<"default format is't support, automatic to use nearest";
        format = info.nearestFormat(format);
    }
    return &format;
}

void DcAudio::startRecord()
{
    QString id = session_id;
    handle_recording_stream = new HandleAudio(prefix_path,id);
    handle_recording_stream->moveToThread(&net_thread);
    audio = new QAudioInput(*setRecord(),this);
    connect(&net_thread,&QThread::finished,handle_recording_stream,&QObject::deleteLater);
    connect(this,&DcAudio::signalCanPost,handle_recording_stream,&HandleAudio::slotSendPost);

    net_thread.start();
    qio = audio->start();

    connect(qio,&QIODevice::readyRead,this,&DcAudio::slotReadStream);
}

const char *  DcAudio::getResultAfter(int t)
{
    QTimer * tim = new QTimer(this);
    tim->setSingleShot(true);
    tim->start(t);
    QEventLoop loop;
    connect(tim,SIGNAL(timeout()),&loop,SLOT(quit()));
    loop.exec();
    return getResult();
}

const char * DcAudio::getResult()
{
    audio->stop();
    QNetworkAccessManager * manager_get_result_stream = new QNetworkAccessManager(this);
    QNetworkReply * reply = manager_get_result_stream->get(QNetworkRequest(QUrl(prefix_path+"session/"+session_id)));

    QEventLoop loop;
    connect(manager_get_result_stream,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
    loop.exec();

    QByteArray qba;
    qba = reply->readAll();
    sendPutToServer();
    return qba.data();
}
void DcAudio::sendPutToServer()
{
    QNetworkAccessManager * manager_put = new QNetworkAccessManager(this);   
    QNetworkReply *reply = manager_put->put(QNetworkRequest(QUrl(prefix_path+"session/"+session_id)),"");

    QEventLoop loop;
    connect(manager_put,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
    loop.exec();

    if(reply->error() != QNetworkReply::NoError){
        qDebug()<<"reset error!";
        qDebug()<<reply->error();
    }
}

void DcAudio::slotReadStream()
{
    qint64 len = audio->bytesReady();
    if(len > 0){
        QByteArray temp(len,0);
        qio->read(temp.data(),len);
        buffer.append(temp);
        if(buffer.size() >= 10000){
            emit signalCanPost(buffer);
            buffer_total.append(buffer);
            buffer.clear();
        }
    }
}

const char *  DcAudio::createSessionID(void)
{
    QNetworkAccessManager * manager_get = new QNetworkAccessManager(this);
    QNetworkReply * reply = manager_get->get(QNetworkRequest(QUrl(prefix_path + "session")));

    QEventLoop loop;
    connect(manager_get,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
    loop.exec();

    if(reply->error() == QNetworkReply::NoError){
        QString raw = reply->readAll();
        QJsonParseError error;
        QJsonDocument jdc = QJsonDocument::fromJson(raw.toUtf8(),&error);
        if(error.error == QJsonParseError::NoError){
            if(jdc.isObject()){
                QVariantMap result = jdc.toVariant().toMap();
                if(result["session_id"].toString() != ""){
                    session_id =  result["session_id"].toByteArray();
                    return session_id.data();
                }
            }
        }
    }else{
        qDebug()<<reply->error();
    }
    reply->deleteLater();
    return nullptr;

}

QString DcAudio::GetRecordFromAudio()
{
    QNetworkAccessManager * manager_post_audio = new QNetworkAccessManager(this);
    QNetworkRequest request;
    request.setUrl(prefix_path+"dc_cmd");
    request.setRawHeader("Content-Type","application/octet-stream");
    QNetworkReply * reply = manager_post_audio->post(request,buffer_total);

    QEventLoop loop;
    connect(manager_post_audio,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));
    loop.exec();
    return reply->readAll();
}

bool DcAudio::deleteSession()
{
    QNetworkAccessManager * manager_del = new QNetworkAccessManager(this);
    QNetworkReply * reply = manager_del->deleteResource(QNetworkRequest(QUrl(prefix_path+"session/"+session_id)));
    if(reply->error() != QNetworkReply::NoError){
        qDebug()<<reply->error();
        return false;
    }else{
        return true;
    }
}
